package com.pine.dcts.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pine.dcts.common.DctsConstant;
import com.pine.dcts.common.DctsException;
import com.pine.dcts.entity.User;
import com.pine.dcts.mapper.RoleMapper;
import com.pine.dcts.mapper.UserMapper;
import com.pine.dcts.query.UserQuery;
import com.pine.dcts.service.RoleService;
import com.pine.dcts.service.UserService;
import com.pine.dcts.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements UserService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleService roleService;
    @Override
    public User getByLoginName(String loginName) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.nested(r->r.eq(User::getLoginName,loginName).or().eq(User::getUserTel,loginName));
        wrapper.and(r->r.eq(User::getStatus, DctsConstant.STATUS_TYPE.NORMAL));
        User user = getOne(wrapper);
        user.setRoles(new HashSet<>(roleMapper.getRoleCodesByUserId(user.getUserId())));
        return user;
    }

    @Override
    public IPage<User> selectPage(UserQuery query) {
        Page page = query.getPage();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(User::getCreateDate);
        return page(page,wrapper);
    }

    /**
     * 检查配置项是否有重复
     *
     * @param entity
     * @return
     */
    private boolean check(User entity) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getLoginName, entity.getLoginName());
        if (entity.getUserId() != null) {
            wrapper.ne(User::getUserId, entity.getUserId());
        }
        return this.count(wrapper) == 0;
    }

    /**
     * 检查配置项是否有重复
     *
     * @param entity
     * @return
     */
    private boolean checkPhone(User entity) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserTel, entity.getUserTel());
        if (entity.getUserId() != null) {
            wrapper.ne(User::getUserId, entity.getUserId());
        }
        return this.count(wrapper) == 0;
    }

    @Transactional
    @Override
    public boolean save(User entity) {
        if(!check(entity)){
            throw new DctsException("该登录账号已存在");
        }
        if(!checkPhone(entity)){
            throw new DctsException("该手机号码已存在");
        }

        entity.setCreateDate(new Date());
        entity.setPassword(SecurityUtils.encode(DctsConstant.INIT_PASSWORD));
        super.save(entity);
        this.roleService.bindRoleUser(entity.getUserId(),entity.getRoleIds());
        return true;
    }
    @Transactional
    @Override
    public boolean updateById(User entity) {
        if(!check(entity)){
            throw new DctsException("该登录账号已存在");
        }
        if(!checkPhone(entity)){
            throw new DctsException("该手机号码已存在");
        }
        this.roleService.bindRoleUser(entity.getUserId(),entity.getRoleIds());
        return super.updateById(entity);
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        idList.forEach(id->{
            this.roleService.deleteRoleBindByUserId(Integer.valueOf((String) id));
            this.removeById(id);
        });
        return true;
    }

    @Override
    public User getById(Serializable id) {
        User user = super.getById(id);
        List<Integer> roleIds = roleMapper.getRoleIdsByUserId(user.getUserId());
        Integer[] rolesz = new Integer[roleIds.size()];
        user.setRoleIds(roleIds.toArray(rolesz));
        return user;
    }
}
